// Jeremy Lee
// Battle Tactics- A turn based strategy game
// Game1.cs- Main game loop
// Assignment Requirements:
// Multiple levels of play- 
// Barack Obama- 
// Animated Character- See Unit.cs
// Timing- 
// Keyboard and Gamepad- 
// Multi-Threaded- Sprite Animations are in a separate thread
using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;
using Microsoft.Xna.Framework.Net;
using Microsoft.Xna.Framework.Storage;

using System.Threading;

namespace BattleTactics
{
    public class Game1 : Microsoft.Xna.Framework.Game
    {
        GraphicsDeviceManager graphics;
        SpriteBatch spriteBatch;
        bool isPaused;
        Level stages;
        Menu selectionMenu;
        Tile[][] test;
        StatusBox test2;
        Unit unit;
        Unit unit2;
        Unit enemy;
        Unit enemy2;
        bool debug = false;
        Song song;
        Texture2D obama;
        Help help;

        public Game1()
        {
            graphics = new GraphicsDeviceManager(this);
            Content.RootDirectory = "Content\\media";
            isPaused = false;
        }
        protected override void Initialize()
        {
            Window.Title = "Battle Tactics";
            IsFixedTimeStep = true;
            TargetElapsedTime = new TimeSpan(0, 0, 0, 0, 1000 / Globl.TARGET_FPS);
            graphics.PreferredBackBufferWidth = Globl.SCREEN_WIDTH;
            graphics.PreferredBackBufferHeight = Globl.SCREEN_HEIGHT;
            graphics.PreferMultiSampling = false;
            graphics.ApplyChanges();
            Globl.content = Content;
            Globl.gsPrev = GamePad.GetState(PlayerIndex.One);
            Globl.ksPrev = Keyboard.GetState();
            Globl.cursor = new Cursor();
            Globl.selected = null;
            help = new Help();
            base.Initialize();
        }
        protected override void LoadContent()
        {
            Globl.blank = Content.Load<Texture2D>("sprites\\blank");
            Globl.font = Content.Load<SpriteFont>("fonts\\miramonte");
            spriteBatch = new SpriteBatch(GraphicsDevice);
            test = new Tile[Globl.TILES_WIDE][];
            for (int i = 0; i < test.Length; i++)
            {
                test[i] = new Tile[Globl.TILES_TALL];
                for (int j = 0; j < test[i].Length; j++)
                {
                    int tmp = Globl.rand.Next(0, 2);
                    test[i][j] = new Tile(tmp);
                    test[i][j].loc = new VectorInt(i, j);
                }
            }
            selectionMenu = new Menu();
            test2 = new StatusBox();
            //        HP,HPMAX,ATK,DEF,RNG,MOV,EXP,LVL,
            unit = new Unit("sprites\\unit", new int[] { 20, 20, 5, 2, 1, 5, 5, 1 }, 1);
            unit.frameRect = new Rectangle[] { new Rectangle(0, 0, 50, 50), new Rectangle(50, 0, 50, 50),
                                               new Rectangle(0, 50, 50, 50), new Rectangle( 50, 50, 50, 50) };
            unit.animateSeq = new int[][] { new int[] { 0, 1 }, new int[] { 0, 2 }, new int[] { 0, 3 } };
            unit.loc = new VectorInt(4, 9);
            test[unit.loc.X][unit.loc.Y].unit = unit;
            unit.alive = true;

            unit2 = new Unit("sprites\\unit", new int[] { 21, 21, 4, 1, 2, 5, 5, 1 }, 1);
            unit2.frameRect = new Rectangle[] { new Rectangle(0, 0, 50, 50), new Rectangle(50, 0, 50, 50),
                                               new Rectangle(0, 50, 50, 50), new Rectangle( 50, 50, 50, 50) };
            unit2.animateSeq = new int[][] { new int[] { 0, 1 }, new int[] { 0, 2 }, new int[] { 0, 3 } };
            unit2.loc = new VectorInt(2, 11);
            test[unit2.loc.X][unit2.loc.Y].unit = unit2;
            unit2.alive = true;

            enemy = new Unit("sprites\\red_unit", new int[] { 15, 15, 3, 2, 1, 5, 5, 1 }, 2);
            enemy.frameRect = new Rectangle[] { new Rectangle(0, 0, 50, 50), new Rectangle(50, 0, 50, 50),
                                               new Rectangle(0, 50, 50, 50), new Rectangle( 50, 50, 50, 50) };
            enemy.animateSeq = new int[][] { new int[] { 0, 1 }, new int[] { 0, 2 }, new int[] { 0, 3 } };
            enemy.loc = new VectorInt(12, 3);
            test[enemy.loc.X][enemy.loc.Y].unit = enemy;
            enemy.alive = true;

            enemy2 = new Unit("sprites\\red_unit", new int[] { 18, 18, 3, 2, 2, 5, 5, 2 }, 2);
            enemy2.frameRect = new Rectangle[] { new Rectangle(0, 0, 50, 50), new Rectangle(50, 0, 50, 50),
                                               new Rectangle(0, 50, 50, 50), new Rectangle( 50, 50, 50, 50) };
            enemy2.animateSeq = new int[][] { new int[] { 0, 1 }, new int[] { 0, 2 }, new int[] { 0, 3 } };
            enemy2.loc = new VectorInt(14, 2);
            test[enemy2.loc.X][enemy2.loc.Y].unit = enemy2;
            enemy2.alive = true;

            obama = Content.Load<Texture2D>("sprites\\barack");

            song = Content.Load<Song>("sounds\\battle");
            MediaPlayer.Play(song);
        }
        protected override void UnloadContent() { }

        protected override void Update(GameTime gameTime)
        {
            if (MediaPlayer.State == MediaState.Stopped)
                MediaPlayer.Play(song);
            Globl.gsCurr = GamePad.GetState(PlayerIndex.One);
            Globl.ksCurr = Keyboard.GetState();
            int elapsedTime = (int)gameTime.ElapsedGameTime.TotalMilliseconds;
            Globl.cursor.update();
            selectionMenu.update();
            // Check for exit
            if (Globl.gsCurr.IsButtonDown(Buttons.Back) || Globl.ksCurr.IsKeyDown(Keys.Escape))
                this.Exit();
            // Pause
            if ((Globl.gsCurr.IsButtonDown(Buttons.Start) && Globl.gsPrev.IsButtonUp(Buttons.Start)) ||
                (Globl.ksCurr.IsKeyDown(Keys.P) && Globl.ksPrev.IsKeyUp(Keys.P)))
                isPaused = !isPaused;
            if (!isPaused)
            {
                Tile tmptle = test[Globl.cursor.loc.X][Globl.cursor.loc.Y];
                List<string> tmp = new List<string>();
                string tmpstr = "";
                switch (tmptle.type)
                {
                    case 0:
                        tmpstr = "Grass";
                        break;
                    case 1:
                        tmpstr = "Trees";
                        break;
                }
                tmp.Add(tmpstr);
                tmpstr = "Move cost: " + tmptle.moveCost;
                tmp.Add(tmpstr);
                Unit tmpUn;
                if (Globl.selected == null)
                    tmpUn = test[Globl.cursor.loc.X][Globl.cursor.loc.Y].unit;
                else
                    tmpUn = Globl.selected;
                if (tmpUn != null)
                {
                    if (tmpUn.owner != 1)
                        tmp.Add("Enemy");
                    string tmp0 = "HP: " + tmpUn.stats[(int)Stats.HP] + "/" + tmpUn.stats[(int)Stats.HPMAX];
                    tmp.Add(tmp0);
                    tmp0 = "Attack: " + tmpUn.stats[(int)Stats.ATK];
                    tmp.Add(tmp0);
                    tmp0 = "Def: " + tmpUn.stats[(int)Stats.DEF];
                    tmp.Add(tmp0);
                    tmp0 = "Lvl: " + tmpUn.stats[(int)Stats.LVL] + " Exp: " + tmpUn.stats[(int)Stats.EXP];
                    tmp.Add(tmp0);
                    if (debug)
                        Console.WriteLine("Unit state is " + tmpUn.state.ToString());
                }
                if (debug)
                    Console.WriteLine("Tile state is " + test[Globl.cursor.loc.X][Globl.cursor.loc.Y].state.ToString());
                test2.removeAll();
                test2.add(tmp);
                test2.update();

                // Menu Selection
                if (tmpUn != null && (tmpUn.state != UnitState.READY && tmpUn.state != UnitState.END))
                {
                    if (tmpUn.state == UnitState.SELECTED)
                    {
                        if ((Globl.gsCurr.IsButtonDown(Buttons.DPadUp) && Globl.gsPrev.IsButtonUp(Buttons.DPadUp)) ||
                                                (Globl.ksCurr.IsKeyDown(Keys.Up) && Globl.ksPrev.IsKeyUp(Keys.Up)))
                        {
                            selectionMenu.changeChoice(2);
                        }
                        else if ((Globl.gsCurr.IsButtonDown(Buttons.DPadDown) && Globl.gsPrev.IsButtonUp(Buttons.DPadDown)) ||
                            (Globl.ksCurr.IsKeyDown(Keys.Down) && Globl.ksPrev.IsKeyUp(Keys.Down)))
                        {
                            selectionMenu.changeChoice(1);
                        }
                        else if ((Globl.gsCurr.IsButtonDown(Buttons.A) && Globl.gsPrev.IsButtonUp(Buttons.A)) ||
                            (Globl.ksCurr.IsKeyDown(Keys.Z) && Globl.ksPrev.IsKeyUp(Keys.Z)))
                        {
                            // Select that menu choice
                            if (selectionMenu.choice == 0)
                                tmpUn.state = UnitState.MOVE;
                            if (selectionMenu.choice == 1)
                                tmpUn.state = UnitState.ATTACK;
                            if (selectionMenu.choice == 2)
                            {
                                tmpUn.state = UnitState.END;
                                Globl.selected = null;
                                for (int i = 0; i < 3; i++)
                                {
                                    selectionMenu.menu[i].disabled = false;
                                    selectionMenu.menu[i].selected = false;
                                }
                                selectionMenu.menu[0].selected = true;
                            }
                        }
                        else if ((Globl.gsCurr.IsButtonDown(Buttons.B) && Globl.gsPrev.IsButtonUp(Buttons.B)) ||
                            (Globl.ksCurr.IsKeyDown(Keys.X) && Globl.ksPrev.IsKeyUp(Keys.X)))
                        {   // Exit selection
                            tmpUn.state = UnitState.READY;
                            Globl.selected = null;
                        }
                    }
                    else if (tmpUn.state == UnitState.MOVE)
                    {
                        if (test[tmpUn.loc.X][tmpUn.loc.Y].state != TileState.MOVE)
                            setMove(tmpUn.loc, tmpUn.stats[(int)Stats.MOV], tmpUn);
                        if ((Globl.gsCurr.IsButtonDown(Buttons.DPadDown) && Globl.gsPrev.IsButtonUp(Buttons.DPadDown)) ||
                            (Globl.ksCurr.IsKeyDown(Keys.Down) && Globl.ksPrev.IsKeyUp(Keys.Down)))
                        {
                            VectorInt tmpV = Globl.cursor.loc + Globl.DOWN;
                            if (tmpV.Y >= Globl.TILES_TALL)
                                tmpV.Y--;
                            if (test[tmpV.X][tmpV.Y].state == TileState.MOVE)
                                Globl.cursor.loc = tmpV;
                        }
                        if ((Globl.gsCurr.IsButtonDown(Buttons.DPadUp) && Globl.gsPrev.IsButtonUp(Buttons.DPadUp)) ||
                            (Globl.ksCurr.IsKeyDown(Keys.Up) && Globl.ksPrev.IsKeyUp(Keys.Up)))
                        {
                            VectorInt tmpV = Globl.cursor.loc + Globl.UP;
                            if (tmpV.Y < 0)
                                tmpV.Y++;
                            if (test[tmpV.X][tmpV.Y].state == TileState.MOVE)
                                Globl.cursor.loc = tmpV;
                        }
                        if ((Globl.gsCurr.IsButtonDown(Buttons.DPadLeft) && Globl.gsPrev.IsButtonUp(Buttons.DPadLeft)) ||
                            (Globl.ksCurr.IsKeyDown(Keys.Left) && Globl.ksPrev.IsKeyUp(Keys.Left)))
                        {
                            VectorInt tmpV = Globl.cursor.loc + Globl.LEFT;
                            if (tmpV.X < 0)
                                tmpV.X++;
                            if (test[tmpV.X][tmpV.Y].state == TileState.MOVE)
                                Globl.cursor.loc = tmpV;
                        }
                        if ((Globl.gsCurr.IsButtonDown(Buttons.DPadRight) && Globl.gsPrev.IsButtonUp(Buttons.DPadRight)) ||
                            (Globl.ksCurr.IsKeyDown(Keys.Right) && Globl.ksPrev.IsKeyUp(Keys.Right)))
                        {
                            VectorInt tmpV = Globl.cursor.loc + Globl.RIGHT;
                            if (tmpV.Y >= Globl.TILES_WIDE)
                                tmpV.X--;
                            if (test[tmpV.X][tmpV.Y].state == TileState.MOVE)
                                Globl.cursor.loc = tmpV;
                        }
                        if ((Globl.gsCurr.IsButtonDown(Buttons.A) && Globl.gsPrev.IsButtonUp(Buttons.A)) ||
                            (Globl.ksCurr.IsKeyDown(Keys.Z) && Globl.ksPrev.IsKeyUp(Keys.Z)))
                        {
                            if (test[Globl.cursor.loc.X][Globl.cursor.loc.Y].unit == null)
                            {
                                test[tmpUn.loc.X][tmpUn.loc.Y].unit = null;
                                tmpUn.loc = Globl.cursor.loc;
                                test[tmpUn.loc.X][tmpUn.loc.Y].unit = tmpUn;
                                tmpUn.state = UnitState.SELECTED;
                                tmpUn.actions[0] = true;
                            }
                            resetTiles();
                            selectionMenu.menu[0].disabled = tmpUn.actions[0];
                        }
                        if ((Globl.gsCurr.IsButtonDown(Buttons.B) && Globl.gsPrev.IsButtonUp(Buttons.B)) ||
                            (Globl.ksCurr.IsKeyDown(Keys.X) && Globl.ksPrev.IsKeyUp(Keys.X)))
                        {
                            tmpUn.state = UnitState.SELECTED;
                            Globl.cursor.loc = tmpUn.loc;
                            resetTiles();
                        }
                    }
                    else if (tmpUn.state == UnitState.ATTACK)
                    {
                        if (test[tmpUn.loc.X][tmpUn.loc.Y].state != TileState.ATTACK)
                            setAttack(tmpUn.loc, tmpUn.stats[(int)Stats.RNG]);
                        if ((Globl.gsCurr.IsButtonDown(Buttons.DPadDown) && Globl.gsPrev.IsButtonUp(Buttons.DPadDown)) ||
                            (Globl.ksCurr.IsKeyDown(Keys.Down) && Globl.ksPrev.IsKeyUp(Keys.Down)))
                        {
                            VectorInt tmpV = Globl.cursor.loc + Globl.DOWN;
                            if (tmpV.Y >= Globl.TILES_TALL)
                                tmpV.Y--;
                            if (test[tmpV.X][tmpV.Y].state == TileState.ATTACK)
                                Globl.cursor.loc = tmpV;
                        }
                        if ((Globl.gsCurr.IsButtonDown(Buttons.DPadUp) && Globl.gsPrev.IsButtonUp(Buttons.DPadUp)) ||
                            (Globl.ksCurr.IsKeyDown(Keys.Up) && Globl.ksPrev.IsKeyUp(Keys.Up)))
                        {
                            VectorInt tmpV = Globl.cursor.loc + Globl.UP;
                            if (tmpV.Y < 0)
                                tmpV.Y++;
                            if (test[tmpV.X][tmpV.Y].state == TileState.ATTACK)
                                Globl.cursor.loc = tmpV;
                        }
                        if ((Globl.gsCurr.IsButtonDown(Buttons.DPadLeft) && Globl.gsPrev.IsButtonUp(Buttons.DPadLeft)) ||
                            (Globl.ksCurr.IsKeyDown(Keys.Left) && Globl.ksPrev.IsKeyUp(Keys.Left)))
                        {
                            VectorInt tmpV = Globl.cursor.loc + Globl.LEFT;
                            if (tmpV.X < 0)
                                tmpV.X++;
                            if (test[tmpV.X][tmpV.Y].state == TileState.ATTACK)
                                Globl.cursor.loc = tmpV;
                        }
                        if ((Globl.gsCurr.IsButtonDown(Buttons.DPadRight) && Globl.gsPrev.IsButtonUp(Buttons.DPadRight)) ||
                            (Globl.ksCurr.IsKeyDown(Keys.Right) && Globl.ksPrev.IsKeyUp(Keys.Right)))
                        {
                            VectorInt tmpV = Globl.cursor.loc + Globl.RIGHT;
                            if (tmpV.Y >= Globl.TILES_WIDE)
                                tmpV.X--;
                            if (test[tmpV.X][tmpV.Y].state == TileState.ATTACK)
                                Globl.cursor.loc = tmpV;
                        }
                        if ((Globl.gsCurr.IsButtonDown(Buttons.A) && Globl.gsPrev.IsButtonUp(Buttons.A)) ||
                            (Globl.ksCurr.IsKeyDown(Keys.Z) && Globl.ksPrev.IsKeyUp(Keys.Z)))
                        {
                            Unit tmpUnit = test[Globl.cursor.loc.X][Globl.cursor.loc.Y].unit;
                            if (tmpUnit != null && tmpUn.owner != tmpUnit.owner)
                            {
                                tmpUn.attack(tmpUnit);
                                if (!tmpUnit.alive)
                                    test[tmpUnit.loc.X][tmpUnit.loc.Y].unit = null;
                                tmpUn.actions[1] = true;
                            }
                            tmpUn.state = UnitState.SELECTED;
                            Globl.cursor.loc = tmpUn.loc;
                            resetTiles();
                            selectionMenu.menu[1].disabled = tmpUn.actions[1];
                        }
                        if ((Globl.gsCurr.IsButtonDown(Buttons.B) && Globl.gsPrev.IsButtonUp(Buttons.B)) ||
                            (Globl.ksCurr.IsKeyDown(Keys.X) && Globl.ksPrev.IsKeyUp(Keys.X)))
                        {
                            tmpUn.state = UnitState.SELECTED;
                            Globl.cursor.loc = tmpUn.loc;
                            resetTiles();
                        }
                    }
                }
                else
                {
                    if (tmpUn != null && tmpUn.state != UnitState.END)
                    {
                        if ((Globl.gsCurr.IsButtonDown(Buttons.A) && Globl.gsPrev.IsButtonUp(Buttons.A)) ||
                            (Globl.ksCurr.IsKeyDown(Keys.Z) && Globl.ksPrev.IsKeyUp(Keys.Z)))
                        {
                            if (tmpUn.owner == 1)
                            {
                                tmpUn.state = UnitState.SELECTED;
                                Globl.selected = tmpUn;
                                for (int i = 0; i < 3; i++)
                                    selectionMenu.menu[i].disabled = tmpUn.actions[i];
                                selectionMenu.menu[0].selected = true;
                                selectionMenu.choice = 0;
                            }
                        }
                    }
                    // Cursor movement
                    if ((Globl.gsCurr.IsButtonDown(Buttons.DPadDown) && Globl.gsPrev.IsButtonUp(Buttons.DPadDown)) ||
                        (Globl.ksCurr.IsKeyDown(Keys.Down) && Globl.ksPrev.IsKeyUp(Keys.Down)))
                    {
                        Globl.cursor.loc += Globl.DOWN;
                        if (Globl.cursor.loc.Y >= Globl.TILES_TALL)
                            Globl.cursor.loc.Y--;
                    }
                    if ((Globl.gsCurr.IsButtonDown(Buttons.DPadUp) && Globl.gsPrev.IsButtonUp(Buttons.DPadUp)) ||
                        (Globl.ksCurr.IsKeyDown(Keys.Up) && Globl.ksPrev.IsKeyUp(Keys.Up)))
                    {
                        Globl.cursor.loc += Globl.UP;
                        if (Globl.cursor.loc.Y < 0)
                            Globl.cursor.loc.Y++;
                    }
                    if ((Globl.gsCurr.IsButtonDown(Buttons.DPadLeft) && Globl.gsPrev.IsButtonUp(Buttons.DPadLeft)) ||
                        (Globl.ksCurr.IsKeyDown(Keys.Left) && Globl.ksPrev.IsKeyUp(Keys.Left)))
                    {
                        Globl.cursor.loc += Globl.LEFT;
                        if (Globl.cursor.loc.X < 0)
                            Globl.cursor.loc.X++;
                    }
                    if ((Globl.gsCurr.IsButtonDown(Buttons.DPadRight) && Globl.gsPrev.IsButtonUp(Buttons.DPadRight)) ||
                        (Globl.ksCurr.IsKeyDown(Keys.Right) && Globl.ksPrev.IsKeyUp(Keys.Right)))
                    {
                        Globl.cursor.loc += Globl.RIGHT;
                        if (Globl.cursor.loc.X >= Globl.TILES_WIDE)
                            Globl.cursor.loc.X--;
                    }
                }
                if (unit.state == UnitState.END && unit2.state == UnitState.END)
                {
                    // Update the enemies
                    if (enemy.alive)
                        findAndKill(enemy);
                    if (enemy2.alive)
                        findAndKill(enemy2);
                    unit.state = UnitState.READY;
                    unit2.state = UnitState.READY;
                    for (int i = 0; i < 3; i++)
                    {
                        unit.actions[i] = false;
                        unit2.actions[i] = false;
                    }
                    Globl.selected = null;
                }
                foreach (Tile[] tarr in test)
                    foreach (Tile t in tarr)
                        t.update();
                unit.updateFrame(elapsedTime);
                unit2.updateFrame(elapsedTime);
                enemy.updateFrame(elapsedTime);
                enemy2.updateFrame(elapsedTime);
            }
            Globl.gsPrev = Globl.gsCurr;
            Globl.ksPrev = Globl.ksCurr;
            if (!unit.alive && !unit2.alive)
                this.Exit();
            if (!enemy.alive && !enemy2.alive)
            {
                unit.loc = new VectorInt(4, 9);
                unit2.loc = new VectorInt(2, 11);
                enemy.loc = new VectorInt(12, 3);
                enemy2.loc = new VectorInt(14, 2);
                unit.stats[(int)Stats.HP] = unit.stats[(int)Stats.HPMAX];
                unit2.stats[(int)Stats.HP] = unit2.stats[(int)Stats.HPMAX];
                enemy.stats[(int)Stats.HP] = enemy.stats[(int)Stats.HPMAX];
                enemy2.stats[(int)Stats.HP] = enemy2.stats[(int)Stats.HPMAX];
                enemy.LevelUp();
                enemy2.LevelUp();
                for( int i=0; i<test.Length; i++ )
                    for( int j=0; j<test[0].Length; j++ )
                    {
                        int tmp = Globl.rand.Next(0, 2);
                        test[i][j] = new Tile(tmp);
                        test[i][j].loc = new VectorInt(i, j);
                    }
                test[unit.loc.X][unit.loc.Y].unit = unit;
                test[unit2.loc.X][unit2.loc.Y].unit = unit2;
                test[enemy.loc.X][enemy.loc.Y].unit = enemy;
                test[enemy2.loc.X][enemy2.loc.Y].unit = enemy2;
                enemy.alive = true;
                enemy2.alive = true;
            }
            base.Update(gameTime);
        }

        protected override void Draw(GameTime gameTime)
        {
            GraphicsDevice.Clear(Color.White);
            spriteBatch.Begin(SpriteBlendMode.AlphaBlend, SpriteSortMode.FrontToBack, SaveStateMode.None);
            foreach (Tile[] tarr in test)
                foreach( Tile t in tarr )
                    t.draw(spriteBatch);
            //Unit tmpUn = test[Globl.cursor.loc.X][Globl.cursor.loc.Y].unit;
            //if (tmpUn != null && tmpUn.state == UnitState.SELECTED )
                //selectionMenu.draw(spriteBatch);
            spriteBatch.Draw(obama, new Vector2(350.0f, 230.0f), new Rectangle(0, 0, obama.Width, obama.Height), Color.White, 0.0f, Vector2.Zero, 1.0f, SpriteEffects.None, 0.2f);
            if (Globl.selected != null && Globl.selected.state == UnitState.SELECTED)
                selectionMenu.draw(spriteBatch);
            test2.draw(spriteBatch);
            Globl.cursor.draw(spriteBatch);
            if (isPaused)
                help.draw(spriteBatch);
            spriteBatch.End();
            base.Draw(gameTime);
        }

        void setMove(VectorInt pos, int moveLeft, Unit moving )
        {
            //stages.grid[pos.X][pos.Y].state = TileState.MOVE;
            test[pos.X][pos.Y].state = TileState.MOVE;
            test[pos.X][pos.Y].stupid = moveLeft;

            VectorInt tmp1 = pos + Globl.UP;
            VectorInt tmp2 = pos + Globl.DOWN;
            VectorInt tmp3 = pos + Globl.RIGHT;
            VectorInt tmp4 = pos + Globl.LEFT;
            int t1, t2, t3, t4;
            t1 = t2 = t3 = t4 = 0;
            Tile tmpTile;
            int tmpCost;
            Unit tmpUnit;

            if (tmp1.Y >= 0)
            {
                //tmpTile = stages.grid[tmp.X][tmp.Y];
                tmpTile = test[tmp1.X][tmp1.Y];
                tmpUnit = tmpTile.unit;
                tmpCost = tmpTile.moveCost;
                if (moveLeft - tmpCost >= 0 && tmpCost > 0 && tmpTile.stupid < moveLeft)
                {
                    if (tmpUnit == null || tmpUnit.owner == moving.owner)
                        t1 = tmpCost;
                }
            }

            if (tmp2.Y < Globl.TILES_TALL)
            {
                //tmpTile = stages.grid[tmp.X][tmp.Y];
                tmpTile = test[tmp2.X][tmp2.Y];
                tmpUnit = tmpTile.unit;
                tmpCost = tmpTile.moveCost;
                if (moveLeft - tmpCost >= 0 && tmpCost > 0 && tmpTile.stupid < moveLeft)
                {
                    if (tmpUnit == null || tmpUnit.owner == moving.owner)
                        t2 = tmpCost;
                }
            }

            if (tmp3.X < Globl.TILES_WIDE)
            {
                //tmpTile = stages.grid[tmp.X][tmp.Y];
                tmpTile = test[tmp3.X][tmp3.Y];
                tmpUnit = tmpTile.unit;
                tmpCost = tmpTile.moveCost;
                if (moveLeft - tmpCost >= 0 && tmpCost > 0 && tmpTile.stupid < moveLeft)
                {
                    if (tmpUnit == null || tmpUnit.owner == moving.owner)
                        t3 = tmpCost;
                }
            }

            if (tmp4.X >= 0)
            {
                //tmpTile = stages.grid[tmp.X][tmp.Y];
                tmpTile = test[tmp4.X][tmp4.Y];
                tmpUnit = tmpTile.unit;
                tmpCost = tmpTile.moveCost;
                if (moveLeft - tmpCost >= 0 && tmpCost > 0 && tmpTile.stupid < moveLeft)
                {
                    if (tmpUnit == null || tmpUnit.owner == moving.owner)
                        t4 = tmpCost;
                }
            }
            if (t1 > 0)
                setMove(tmp1, moveLeft - t1, moving);
            if (t2 > 0)
                setMove(tmp2, moveLeft - t2, moving);
            if (t3 > 0)
                setMove(tmp3, moveLeft - t3, moving);
            if (t4 > 0)
                setMove(tmp4, moveLeft - t4, moving);
        }
        void setAttack(VectorInt pos, int moveLeft)
        {
            //stages.grid[pos.X][pos.Y].state = TileState.MOVE;
            test[pos.X][pos.Y].state = TileState.ATTACK;

            VectorInt tmp1 = pos + Globl.UP;
            VectorInt tmp2 = pos + Globl.DOWN;
            VectorInt tmp3 = pos + Globl.RIGHT;
            VectorInt tmp4 = pos + Globl.LEFT;
            int t1, t2, t3, t4;
            t1 = t2 = t3 = t4 = 0;
            Tile tmpTile;

            if (tmp1.Y >= 0)
            {
                //tmpTile = stages.grid[tmp.X][tmp.Y];
                tmpTile = test[tmp1.X][tmp1.Y];
                if (moveLeft - 1 >= 0 && tmpTile.state == TileState.NONE)
                    t1 = 1;
            }

            if (tmp2.Y < Globl.TILES_TALL)
            {
                //tmpTile = stages.grid[tmp.X][tmp.Y];
                tmpTile = test[tmp2.X][tmp2.Y];
                if (moveLeft - 1 >= 0 && tmpTile.state == TileState.NONE)
                    t2 = 1;
            }

            //tmpTile = stages.grid[tmp.X][tmp.Y];
            if (tmp3.X < Globl.TILES_WIDE)
            {
                tmpTile = test[tmp3.X][tmp3.Y];
                if (moveLeft - 1 >= 0 && tmpTile.state == TileState.NONE)
                    t3 = 1;
            }

            //tmpTile = stages.grid[tmp.X][tmp.Y];
            if (tmp4.X >= 0)
            {
                tmpTile = test[tmp4.X][tmp4.Y];
                if (moveLeft - 1 >= 0 && tmpTile.state == TileState.NONE)
                    t4 = 1;
            }
            if (t1 > 0)
                setAttack(tmp1, moveLeft - t1);
            if (t2 > 0)
                setAttack(tmp2, moveLeft - t2);
            if (t3 > 0)
                setAttack(tmp3, moveLeft - t3);
            if (t4 > 0)
                setAttack(tmp4, moveLeft - t4);
        }
        void resetTiles()
        {
            foreach (Tile[] tarr in test)
                foreach (Tile t in tarr)
                {
                    t.state = TileState.NONE;
                    t.stupid = 0;
                }
        }

        void findAndKill(Unit un)
        {
            // Create a list of moveable tiles
            List<SomeData> something = new List<SomeData>();
            setMove(un.loc, un.stats[(int)Stats.MOV], un);
            int count = 0;
            foreach (Tile[] tArr in test)
                foreach (Tile t in tArr)
                    if (t.state == TileState.MOVE)
                    {
                        SomeData tmp;
                        tmp.tile = t;
                        tmp.attackable = new List<Tile>();
                        something.Add(tmp);
                    }
            resetTiles();
            // For each moveable tile, create a list of tiles with attackable units
            foreach (SomeData sd in something )
            {
                setAttack(sd.tile.loc, un.stats[(int)Stats.RNG]);
                foreach (Tile[] tArr in test)
                    foreach (Tile t in tArr)
                        if (t.state == TileState.ATTACK && t.unit != null && t.unit.owner != un.owner)
                        {
                            sd.attackable.Add(t);
                            count++;
                        }
                resetTiles();
            }
            // Go through every attackable tile, and find the one you bring to the lowest health
            Tile moveTarget = null;
            Tile targetTile = null;
            if (count > 0)
            {
                int minHP = int.MaxValue;
                for (int i = 0; i < something.Count; i++)
                {
                    for (int j = 0; j < something[i].attackable.Count; j++)
                    {
                        int tmpHP = something[i].attackable[j].unit.stats[(int)Stats.HP] -
                                    (un.stats[(int)Stats.ATK] - something[i].attackable[j].unit.stats[(int)Stats.DEF]);
                        if (tmpHP < minHP && something[i].tile.unit== null )
                        {
                            minHP = tmpHP;
                            moveTarget = something[i].tile;
                            targetTile = something[i].attackable[j];
                        }
                    }
                }
                un.attack(targetTile.unit);
                if (!targetTile.unit.alive)
                    targetTile.unit = null;
            }
            else    // If there was no attackable tile, go to closest tile
            {
                int minDist = int.MaxValue;
                for (int i = 0; i < something.Count; i++)
                {
                    int tmpDist = Math.Abs(something[i].tile.loc.X - unit.loc.X) + Math.Abs(something[i].tile.loc.Y - unit.loc.Y);
                    if (tmpDist < minDist)
                    {
                        minDist = tmpDist;
                        moveTarget = something[i].tile;
                    }
                    tmpDist = Math.Abs(something[i].tile.loc.X - unit2.loc.X) + Math.Abs(something[i].tile.loc.Y - unit2.loc.Y);
                    if (tmpDist < minDist && something[i].tile.unit == null)
                    {
                        minDist = tmpDist;
                        moveTarget = something[i].tile;
                    }
                }
            }

            test[un.loc.X][un.loc.Y].unit = null;
            test[moveTarget.loc.X][moveTarget.loc.Y].unit = un;
        }
    }
}
